package com.bdqn.sys.realm;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bdqn.common.utitls.SystemConstants;
import com.bdqn.sys.entity.Permission;
import com.bdqn.sys.entity.User;
import com.bdqn.sys.service.PermissionService;
import com.bdqn.sys.service.RoleService;
import com.bdqn.sys.service.UserService;
import com.bdqn.sys.vo.LoginUserVo;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class UserRealm extends AuthorizingRealm {





    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private PermissionService permissionService;

    /**
     *
     * @param authenticationToken
     * @return身份验证 为当前登录的用户进行身份验证
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        try {
            String username=authenticationToken.getPrincipal().toString();//getPrincipal()获取自定义Realm身份信息
            //调用根据用户名查询用户信息的方法
            User loginUser = userService.findByUserName(username);
            if (loginUser!=null){
                //创建登录用户对象,传入用户信息,角色列表,权限列表
                LoginUserVo loginUserVo=new LoginUserVo();
                loginUserVo.setUser(loginUser);//当前登录用户
                /*****************************关联权限菜单代码开始  ***********************************/
                //普通用户需要结合当前角色、权限去查询菜单
                QueryWrapper<Permission> queryWrapper=new QueryWrapper<Permission>();
                queryWrapper.eq("type",SystemConstants.Type_PERMISSION);
                //根据当前用户ID查询用户拥有的角色ID
                Set<Integer> currentUserRoleIds = userService.findUserRoleByUserId(loginUser.getId());
                //创建集合保存菜单
                Set<Integer> pids=new HashSet<Integer>();
                //循环遍历角色id
                for (Integer roleId : currentUserRoleIds) {
                    //根据角色ID查询每个角色有哪些权限
                    Set<Integer>  permissionIds=roleService.findRolePermissionIdByRoleId(roleId);//根据角色的Id查询权限菜单
                    //将查询出来的权限添菜单ID添加到集合中
                    pids.addAll(permissionIds);
                }
                //创建集合保存权限对象
                List<Permission> list=new ArrayList<Permission>();
                //判断集合中是否存在权限数据
                if (pids!=null&&pids.size()>0){
                    //查询角色拥有权限Id
                    queryWrapper.eq("id",pids);
                    //根据角色id查询权限菜单
                    list=permissionService.list(queryWrapper);

                }
                //创建集合保存权限的编码
                Set<String> percodes=new HashSet<String>();
                //循环遍历list集合
                for (Permission Permission : list) {
                    //将每个菜单对应的权限放到权限编码的集合中
                    percodes.add(Permission.getPercode());
                }
                //设置权限
                loginUserVo.setPermissions(percodes);


                /*****************************关联权限菜单代码结束  ***********************************/


                //创建盐值
                ByteSource salt=ByteSource.Util.bytes(loginUser.getSalt());
                //创建身份验证信息对象 参数一当前登录对象 参数二是密码 参数三是盐值  第四个是域名（可以自定义或者是为空都可以）不能双引号的空
                SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(loginUserVo,loginUser.getLoginpwd(),salt,getName());
                return simpleAuthenticationInfo;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }









    /**
     *授权 为当前登录的用户授权相应的权限
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //创建授权对象
        SimpleAuthorizationInfo simpleAuthenticationInfo=new SimpleAuthorizationInfo();
        //获取当前登录主体对象
        LoginUserVo loginUserVo = (LoginUserVo) principalCollection.getPrimaryPrincipal();
        //获取当前用户拥有的权限
        Set<String> permissions = loginUserVo.getPermissions();
        //判断当前用户是否超级管理员
        if (loginUserVo.getUser().getType()== SystemConstants.USER_TYPE_SUPER){
            //超级管理员拥有所有权限
            simpleAuthenticationInfo.addStringPermission("*.*");
        }else {
            //单独授权
            if (permissions!=null&&permissions.size()>0){
                //授权
                simpleAuthenticationInfo.addStringPermissions(permissions);

            }
        }
        return simpleAuthenticationInfo;
    }


}
